<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8"/>
    <title>this丢失问题</title>
</head>
<body>
<script>
    //this丢失问题主要出现在传递对象方法的时候

    let obj = {
        age: 24,
        getAge() {
            console.log(this.age);
        },
    };

    let func1 = obj.getAge;


    // func1()

    /*
     * 在可以获取当前对象的情况下可以使用bind进行固定绑定
     * */
    let func2 = obj.getAge.bind(obj)
    func2()

    /*
    * class中的方法可以在构造函数内进行bind 因为class的constructor中的this是当前对象
    * 或者使用箭头函数
    * */

    class Person {
        constructor(name, age) {
            this.name = name
            this.age = age

            this.getAge = this.getAge.bind(this)
        }

        getAge() {
            console.log(this.age)
        }

        getName = () => {
            console.log(this.name)
        }
    }

    let person = new Person("Lily", 25)
    func1 = person.getAge
    func2 = person.getName
    func1()
    func2()


    /*
    *包装器函数因为是通用方法，不知道会传入什么对象，但是有一个特点，即返回函数的this是当前对象
    * 我们只要将外层函数传入的函数使用call的方式调用即可
    * */

    function decor(f, ms) {
        return function () {
            setTimeout(() => {
                f.call(this, arguments)
            }, ms)
        }
    }

    /*
    * 但是装饰器模式使用的时候都会将传入的对象方法放入装饰器将返回值重新赋值为对象的方法
    * 如果不是原路返回重新赋值的话会出现this丢失的问题
    *
    *     let a = decor(obj.getAge, 2000)
          a()
          *
          * 比如像上面这样写的话this还是会丢失
    * */
    obj.getAge = decor(obj.getAge, 2000)
    obj.getAge()


</script>
</body>
</html>
